const express = require('express');
const app = express();

// 路由路径和请求方法一起定义了请求的端点，它可以是字符串、字符串模式或者正则表达式。

//匹配根路径的请求
app.get('/', (req, res) => {
    res.send('root');
})

// 匹配 /about 路径的请求
app.get('/about', (req, res) => {
    res.send('About Page');
})

app.get('/contact', (req, res) => {
    res.send('Contact Page');
})

//匹配 /random.text 路径的请求
app.get('/random.text',function(reg,res){
    res.send('random.text')
});


// 匹配 字符串模式
// 匹配 acd 和 abcd，b可有可无
app.get('/ab?cd', (req, res) => {
    res.send('ab?cd');
})

// 匹配 /ab/******
app.get('/ab/:id',function(req, res){
    res.send('aaaaaaa')
});

// 匹配 abcd、abbcd、abbbcd等,b可以一次或多次
app.get('/ab+cd',function(req, res){
    res.send('ab+cd');
});

// 匹配 abcd、abxcd、abRABDoMcd、ab123cd等
app.get('/ab*cd',function(req, res){
    res.send('ab*cd')
});

// 匹配 /abe 和 /abcde
app.get('/ab(cd)?e',function(req, res){
    res.send('ab(cd)?e');
});


// 使用正则表达式的路由路径示例:

// 匹配任何路径中含有 a 的路径:
app.get(/a/,function(req, res){
    res.send('/a/');
});

// 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等，以fly结尾
app.get(/.*fly$/,function(req, res){
    res.send('/.*fly$/');
});

app.get('/profile/:id', (req, res) => {
    res.send('Profile Page ' + req.params.id);
})




// 可以为请求处理提供多个回调函数，其行为类似 中间件。
// 唯一的区别是这些回调函数有可能调用 next(route”)方法而略过其他路由回调函数。
// 可以利用该机制为路由定义前提条件，如果在现有路径上继续执行没有意义，则可将控制权交给剩下的路径。

app.get('/example/a',function(req, res){
    res.send('Hello from A!');
});
// 使用多个回调函数处理路由(记得指定 next 对象)
app.get('/example/b',function(req, res, next){
    console.log('response will be sent by the next function ...');
    next();
},function(req,res){
    res.send('Hello from B!');
});


// 使用回调函数数组处理路由
var cb0 =function(req,res, next){
    console.log('CB0')
    next()
}
var cbl=function(req,res,next){
    console.log('CB1')
    next()
}
var cb2 =function(req,res){
    res.send('Hello from c!')
}
app.get('/example/c',[cb0,cb1,cb2])
// 这句意思是：执行 cb0 回调函数，
// 如果执行过程中 next 方法被调用，则将控制权交给 cb1，
// 依此类推,一旦res.send()被调用，则结束。后面再写next()，则不会执行。

// 例如下面代码：func1为验证函数，
// 如果验证通过，则执行func2。
const func1 = function(req, res, next) {
    // 验证逻辑,如验证token
    const isValid = true;
    if (isValid) {
        next();
    } else {
        res.sendStatus(400);
    }
    next();
}
const func2 = function(req, res) {
    // 执行func2
res.send({list:[1,2,3]})
}
app.get('/home',[func1,func2])
// func1可以共用
// 如下面代码与上面的home共用一个func1：
app.get("/list",[func1],(req,res)=>{
    res.send("list")
})

// 上面代码，app.get('/home',[func1,func2]),复杂代码写在了func1和func2中，使代码结构清晰，如果func1有计算结果要传给func2，
// 则需要使用next()方法，将计算结果传给func2。在next()前加上res一个属性，如res.result=result，在func2中使用res.result即可。



// 混合使用函数和函数数组处理路由:
var cb0 =function(req,res,next){
    console.log('CB0')
    next()
}



app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
})
